package com.supersonic.backend.DAOImpl;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.supersonic.backend.DAO.IBaseDAO;
import com.supersonic.backend.model.BaseModel;

@Repository(value="baseDao")
//@Transactional
public class BaseDAOImpl<T, ID extends Serializable> implements IBaseDAO<T, ID> {

	@Autowired
	protected SessionFactory sessionFactory;
	
	protected Session getSession() {
		return sessionFactory.getCurrentSession();
	}
	
	@Override
	public void save(T entity) {
		if(entity instanceof BaseModel) {
			((BaseModel)entity).setCreatedDatetime(new Date());
		}
		getSession().save(entity);
	}

	@Override
	public void delete(T entity) {
		getSession().delete(entity);
	}

	@Override
	public void deleteById(Class<T> entityClass, ID id) {
		delete(this.findById(entityClass, id));
	}

	@Override
	public void update(T entity) {
		if(entity instanceof BaseModel) {
			((BaseModel)entity).setUpdateDatetime(new Date());
		}
		getSession().update(entity);
		
	}

	@SuppressWarnings("unchecked")
	@Override
	public T findById(Class<T> entityClass, ID id) {
		return (T) getSession().get(entityClass, id);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> findAll(Class<T> entityClass) {
		return getSession().createQuery("from " + entityClass.getName()).list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Object> find(String hql, Map<String,String> params) {
		Query query = this.getSession().createQuery(hql);  
		if(params!=null) {
			for (Entry<String,String> entry : params.entrySet()) {  
				query.setString(entry.getKey(), entry.getValue());
			}  
		}        
        return query.list();  
	}

	@Override
	public void saveOrUpdate(T entity) {
		if(entity instanceof BaseModel) {
			((BaseModel)entity).setUpdateDatetime(new Date());
		}
		getSession().saveOrUpdate(entity);
	}

}
